package com.ys.service.sys.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ys.dto.DtreeSqlDto;
import com.ys.dto.YsTreeDto;
import com.ys.entity.sys.TbCompanyInfo;
import com.ys.entity.sys.TsOrganizationInfo;
import com.ys.entity.sys.TsUserInfo;
import com.ys.enume.sys.TsOrganizationInfoEnum;
import com.ys.mapper.sys.SysMapper;
import com.ys.mapper.sys.TbCompanyInfoMapper;
import com.ys.mapper.sys.TsOrganizationInfoMapper;
import com.ys.service.sys.TsOrganizationInfoService;
import com.ys.util.RandomUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.R;

@Service("tsOrganizationInfoService")
public class TsOrganizationInfoServiceImpl implements TsOrganizationInfoService {
	@Autowired
	private TbCompanyInfoMapper tbCompanyInfoMapper;
	@Autowired
	private SysMapper sysMapper;
	@Autowired
	private TsOrganizationInfoMapper tsOrganizationInfoMapper;

	@Override
	@Transactional
	public void repairNode(String guidTsOrganizationInfo) throws Exception {
		TsOrganizationInfo tsOrganizationInfo = new TsOrganizationInfo().setGuid(guidTsOrganizationInfo).queryFirst();
		if (tsOrganizationInfo.getPguid().equals("root")) {
			return;
		} else {
			
			TsOrganizationInfo pTsOrganizationInfo = new TsOrganizationInfo().setGuid(tsOrganizationInfo.getPguid()).queryFirst();
			
			if (pTsOrganizationInfo.getNodeLft() == null || pTsOrganizationInfo.getNodeRgt() == null) {
				return;
			} else {
				Integer nodeRgt = pTsOrganizationInfo.getNodeRgt();
				sysMapper.updateTsOrganizationInfoNodeLftAddTwo(nodeRgt);
				sysMapper.updateTsOrganizationInfoNodeRgtAddTwo(nodeRgt);
				
				tsOrganizationInfo.setNodeLft(nodeRgt);
				tsOrganizationInfo.setNodeRgt(nodeRgt + 1);
				tsOrganizationInfoMapper.update(tsOrganizationInfo);
			}
		}
	}

	@Override
	@Transactional
	public R add(Long pid, String orgName, String orgKind) {
		
		TsOrganizationInfo pEntity = new TsOrganizationInfo().setId(pid).queryFirst();
		if (pEntity == null) {
			return R.error("上级不存在");
		}
		
		if (orgKind == null || orgKind.length() == 0) {
			return R.error("机构类别不能为空");
		}
		
		Integer pNodeRgt = pEntity.getNodeRgt();
		sysMapper.updateTsOrganizationInfoNodeLftAddTwo(pNodeRgt);
		sysMapper.updateTsOrganizationInfoNodeRgtAddTwo(pNodeRgt);
		
		TsOrganizationInfo entity = null;
		{
			String guid = RandomUtil.getGUID();
			String pguid = pEntity.getGuid();
			String orgid = getNextOrgId(orgKind);
			String cid = pEntity.getCid();
			String cidName = pEntity.getCidName();
			String orgPath = pEntity.getOrgPath() + "." + orgid;
			String orgPathName = pEntity.getOrgPathName() + "→" + orgName;
			String orgPathAll = orgPath;
			String orgPathNameAll = orgPathName;
			String orgManagers = null;
			String orgManagersAll = null;
			String iconClass = null;
			Integer deleted = 0;
			String createUser = ShiroUtils.getUserId();
			String updateUser = null;
			Integer levels = pEntity.getLevels() + 1;
			Integer maxlevels = 9;
			String deptPath = orgPath;
			String deptPathName = orgPathName;
			String deptName = orgName;
			String headUserId = null;
			Integer nodeLft = pEntity.getNodeRgt();
			Integer nodeRgt = pEntity.getNodeRgt() + 1;
			Integer floor = pEntity.getFloor() + 1;
			
			entity = TsOrganizationInfo.tsOrganizationInfo(
					pid, guid, pguid, orgid, orgName, orgKind,
					cid, cidName, orgPath, orgPathName, orgPathAll,
					orgPathNameAll, orgManagers, orgManagersAll, iconClass, deleted,
					createUser, updateUser, levels,
					maxlevels, deptPath, deptPathName, deptName, headUserId, nodeLft, nodeRgt, floor, 1);
			tsOrganizationInfoMapper.insert(entity);
		}
		
		// 添加公司信息
		TbCompanyInfo tbCompanyInfo = null;
		if(orgKind.equals(TsOrganizationInfoEnum.OrgKind.COMPANY.value)) {
			String vId = entity.getOrgid();
			String vName = orgName;
			tbCompanyInfo = TbCompanyInfo.tbCompanyInfo(vId, vName, null,
					null,null,null,null,null,
					null,null,null,1);
			tbCompanyInfoMapper.insert(tbCompanyInfo);
		}
		
		return R.ok();
	}

	@Override
	public R edit(Long id, String orgName, String headUserId, int status) {
		
		TsOrganizationInfo entity = new TsOrganizationInfo().setId(id).queryFirst();
		
		// 验证负责人
		TsUserInfo tsUserInfo = new TsUserInfo().setUserId(headUserId).queryFirst();
		if (!tsUserInfo.getOrgId().equals(entity.getId())) {
			return R.error("该工号不在所在部门，无法设置");
		}

		entity.setOrgName(orgName)
			.setHeadUserId(headUserId)
			.setStatus(status);
		tsOrganizationInfoMapper.update(entity);
		
		if (entity.getOrgKind().equals(TsOrganizationInfoEnum.OrgKind.COMPANY.value)) {
			TbCompanyInfo tbCompanyInfo = new TbCompanyInfo().setVid(entity.getOrgid()).queryFirst();
			tbCompanyInfo.setVname(entity.getOrgName());
			tbCompanyInfoMapper.update(tbCompanyInfo);
		}
		
		return R.ok();
	}

	@Override
	public void repairUserOrg(String userId) {
		TsUserInfo tsUserInfo = new TsUserInfo().setUserId(userId).queryFirst();
		if (tsUserInfo == null) {
			return;
		} else if (tsUserInfo.getOrganizationid() == null || tsUserInfo.getOrganizationid().length() == 0) {
			return;
		}
		
		TsOrganizationInfo tsOrganizationInfo = new TsOrganizationInfo().setGuid(tsUserInfo.getOrganizationid()).queryFirst();
		if (tsOrganizationInfo == null) {
			return;
		}
	}

	/**
	 * 清空树信息
	 */
	@Override
	public void clearTreeInfo() {
		sysMapper.clearTsOrganizationInfoTreeNode();
	}

	@Override
	public void repairTreeInfo(String guid) {

		System.out.println("guid--" + guid);
		TsOrganizationInfo entity = new TsOrganizationInfo().setGuid(guid).queryFirst();
		
		TsOrganizationInfo pEntity = new TsOrganizationInfo().setGuid(entity.getPguid()).queryFirst();
		Integer pNodeRgt = pEntity.getNodeRgt();
		if (pNodeRgt == null) {
			return;
		}
		sysMapper.updateTsOrganizationInfoNodeLftAddTwo(pNodeRgt);
		sysMapper.updateTsOrganizationInfoNodeRgtAddTwo(pNodeRgt);
		entity.setNodeLft(pNodeRgt)
			.setNodeRgt(pNodeRgt + 1)
			.setFloor(pEntity.getFloor() + 1)
			.setPid(pEntity.getId());
		tsOrganizationInfoMapper.update(entity);
		
	}
	
	private String getNextOrgId(String orgKind) {
		if (orgKind == null || orgKind.length() == 0) {
			return null;
		} else if (orgKind.equals(TsOrganizationInfoEnum.OrgKind.COMPANY.value)) {
			return "C" + sysMapper.getNextOrgId(orgKind);
		} else {
			return "D" + sysMapper.getNextOrgId(orgKind);
		}
	}

	@Override
	public DtreeSqlDto dtree() {
		
		DtreeSqlDto.StatusDto status = DtreeSqlDto.StatusDto.init(200, "");

		List<DtreeSqlDto.DataDto> data = new ArrayList<DtreeSqlDto.DataDto>();
		List<TsOrganizationInfo> listTsOrganizationInfo = new TsOrganizationInfo()
				.where("A.OrgKind != 'user'")
				.setOrderby("A.Orgid asc")
				.setStatus(1)
				.queryList();
		// 处理部门数据，方便遍历
		Map<String, List<TsOrganizationInfo>> MAP_PGUID_LIST = new HashMap<String, List<TsOrganizationInfo>>();
		for(TsOrganizationInfo tsOrganizationInfo : listTsOrganizationInfo) {
			List<TsOrganizationInfo> listValue = MAP_PGUID_LIST.containsKey(tsOrganizationInfo.getPguid()) ? MAP_PGUID_LIST.get(tsOrganizationInfo.getPguid()) : new ArrayList<TsOrganizationInfo>();
			listValue.add(tsOrganizationInfo);
			MAP_PGUID_LIST.put(tsOrganizationInfo.getPguid(), listValue);
		}
		
		// 一级菜单
		{
			TsOrganizationInfo tsOrganizationInfoRoot = new TsOrganizationInfo().setPguid("root").queryFirst();
			String id = tsOrganizationInfoRoot.getId().toString();
			String title = tsOrganizationInfoRoot.getOrgName();
			String parentId = tsOrganizationInfoRoot.getPguid();
			
			// 二级菜单
			List<DtreeSqlDto.DataDto> children = getChildren(tsOrganizationInfoRoot, MAP_PGUID_LIST);
			
			DtreeSqlDto.DataDto dataDto1 = new DtreeSqlDto.DataDto(id, title, parentId, DtreeSqlDto.DataDto.initCheckArr(null), children);
			data.add(dataDto1);
		}
		return new DtreeSqlDto(status, data);
	}
	
	private List<DtreeSqlDto.DataDto> getChildren(TsOrganizationInfo current, Map<String, List<TsOrganizationInfo>> MAP_PGUID_LIST) {
		
		List<TsOrganizationInfo> listTsOrganizationInfo = MAP_PGUID_LIST.get(current.getGuid());
		List<DtreeSqlDto.DataDto> children = new ArrayList<DtreeSqlDto.DataDto>();
		if (listTsOrganizationInfo == null) {
			return null;
		} else {
			for(TsOrganizationInfo tsOrganizationInfo : listTsOrganizationInfo) {
				String id = tsOrganizationInfo.getId().toString();
				String title = tsOrganizationInfo.getOrgName();
				String parentId = tsOrganizationInfo.getPid().toString();
				
				List<DtreeSqlDto.DataDto> childrenSub = getChildren(tsOrganizationInfo, MAP_PGUID_LIST);
				DtreeSqlDto.DataDto dataDtoSub = new DtreeSqlDto.DataDto(id, title, parentId, DtreeSqlDto.DataDto.initCheckArr(null), childrenSub);
				children.add(dataDtoSub);
			}
		}
		
		return children;
	}

	@Override
	public YsTreeDto ysTree() {

		List<YsTreeDto.DataDto> data = new ArrayList<YsTreeDto.DataDto>();
		List<TsOrganizationInfo> listTsOrganizationInfo = new TsOrganizationInfo()
				.where("A.OrgKind != 'user'")
				.setOrderby("A.Orgid asc")
				.setStatus(1)
				.queryList();
		// 处理部门数据，方便遍历
		Map<String, List<TsOrganizationInfo>> MAP_PGUID_LIST = new HashMap<String, List<TsOrganizationInfo>>();
		for(TsOrganizationInfo tsOrganizationInfo : listTsOrganizationInfo) {
			List<TsOrganizationInfo> listValue = MAP_PGUID_LIST.containsKey(tsOrganizationInfo.getPguid()) ? MAP_PGUID_LIST.get(tsOrganizationInfo.getPguid()) : new ArrayList<TsOrganizationInfo>();
			listValue.add(tsOrganizationInfo);
			MAP_PGUID_LIST.put(tsOrganizationInfo.getPguid(), listValue);
		}
		
		// 一级菜单
		{
			TsOrganizationInfo tsOrganizationInfoRoot = new TsOrganizationInfo().setPguid("root").queryFirst();
			String id = tsOrganizationInfoRoot.getId().toString();
			String title = tsOrganizationInfoRoot.getOrgName();
			
			// 二级菜单
			List<YsTreeDto.DataDto> children = getYsTreeSub(tsOrganizationInfoRoot, MAP_PGUID_LIST);
			
			YsTreeDto.DataDto dataDto1 = new YsTreeDto.DataDto(id, title, children);
			data.add(dataDto1);
		}
		return new YsTreeDto(data);
	}
	
	private List<YsTreeDto.DataDto> getYsTreeSub(TsOrganizationInfo current, Map<String, List<TsOrganizationInfo>> MAP_PGUID_LIST) {
		
		List<TsOrganizationInfo> listTsOrganizationInfo = MAP_PGUID_LIST.get(current.getGuid());
		List<YsTreeDto.DataDto> children = new ArrayList<YsTreeDto.DataDto>();
		if (listTsOrganizationInfo == null) {
			return null;
		} else {
			for(TsOrganizationInfo tsOrganizationInfo : listTsOrganizationInfo) {
				String id = tsOrganizationInfo.getId().toString();
				String title = tsOrganizationInfo.getOrgName();
				
				List<YsTreeDto.DataDto> childrenSub = getYsTreeSub(tsOrganizationInfo, MAP_PGUID_LIST);
				YsTreeDto.DataDto dataDtoSub = new YsTreeDto.DataDto(id, title, childrenSub);
				children.add(dataDtoSub);
			}
		}
		
		return children;
	}
}
